package simulaco.business;

import gminet.infra.business.BusinessException;
import gminet.infra.business.BusinessObject;
import gminet.infra.db.Transaction;
import gminet.infra.db.TransactionException;

import java.sql.Connection;
import java.util.List;

import simulaco.dao.QuestaoItemDAO;
import simulaco.dto.Questao;
import simulaco.dto.QuestaoItem;
import simulaco.dto.Situacao;

public class QuestaoItemBusiness extends BusinessObject {

    public static List<QuestaoItem> findByQuestao(Questao questao, Connection conn) throws TransactionException {

        return QuestaoItemDAO.findByQuestao(questao, conn);
    }

    public static QuestaoItem insert(QuestaoItem questaoItem) throws BusinessException, TransactionException {

        QuestaoItem newQuestaoItem = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            // QUESTAO ITEM
            questaoItem.setCodigo(QuestaoItemDAO.getNextCodigo(questaoItem.getQuestao(), conn));
            QuestaoItemDAO.insert(questaoItem, conn);
            // COMMIT
            transaction.commit();
            //
            newQuestaoItem = questaoItem;
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
        return newQuestaoItem;
    }

    protected static void insertFromQuestao(Questao questao, Connection conn) throws BusinessException,
            TransactionException {

        List<QuestaoItem> itensNovo = questao.getListaItens();
        if (itensNovo.size() == 0) {
            throw new BusinessException("Nenhum item foi incluido. Pelo menos um item deve ser adicionado.");
        }
        boolean temItemCorreto = false;
        for (QuestaoItem questaoItem : itensNovo) {
            questaoItem.setQuestao(questao);
            if (QuestaoItemDAO.findByPK(questaoItem, conn) == null) {
                questaoItem.setCodigo(QuestaoItemDAO.getNextCodigo(questao, conn));
                questaoItem.setSituacao(Situacao.HABILITADO);
                if (questaoItem.isItemCorreto()) {
                    if (!temItemCorreto) {
                        temItemCorreto = true;
                    } else {
                        throw new BusinessException(
                                "Mais de um item marcado como correto. Somente um item deve ser o correto.");
                    }
                }
                QuestaoItemDAO.insert(questaoItem, conn);
            }
        }
        if (!temItemCorreto) {
            throw new BusinessException("Nenhum item marcado como correto. Pelo menos um item deve ser correto.");
        }
    }

    public static void update(QuestaoItem questaoItem) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            QuestaoItemDAO.update(questaoItem, conn);
            // COMMIT
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    protected static void updateFromQuestao(Questao questao, Connection conn) throws BusinessException,
            TransactionException {

        // EXCLUI ITENS ANTERIORES DA QUESTAO
        deleteByQuestao(questao, conn);
        // INCLUI NOVOS ITENS DA QUESTAO
        insertFromQuestao(questao, conn);
    }

    public static void updateStatus(QuestaoItem questaoItem) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            //
            QuestaoItem auxQuestaoItem = QuestaoItemDAO.findByPK(questaoItem, conn);
            auxQuestaoItem.setSituacao(questaoItem.getSituacao());
            QuestaoItemDAO.update(auxQuestaoItem, conn);
            // COMMIT
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    public static void delete(QuestaoItem questaoItem) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            QuestaoItemDAO.delete(questaoItem, conn);
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    protected static void deleteByQuestao(Questao questao, Connection conn) throws BusinessException,
            TransactionException {

        QuestaoItemDAO.deleteByQuestao(questao, conn);
    }

}
